package hikari.gui.panels.particle;

import com.gooddies.events.ValueChangedEvent;
import com.gooddies.swing.RowLayout;
import com.gooddies.swing.hCheckBox;
import com.gooddies.texteditors.DefaultFloatTextField;
import hikari.gui.guicomponents.hLabel;
import hikari.math.CircleDrawer;
import hikari.persistence.file.FileSection;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import org.swig.jirr.IParticleCylinderEmitter;
import org.swig.jirr.IParticleEmitter;
import org.swig.jirr.IParticleSystemSceneNode;
import org.swig.jirr.IVideoDriver;
import org.swig.jirr.vector3df;

/**
 * @author Dmitry
 */
public class CylinderEmitterEditorPanel extends EmitterEditorPanel {

    private Vector3dEditor centerEditor;
    private IParticleCylinderEmitter emitter;
    private DefaultFloatTextField radiusEditBox;
    private DefaultFloatTextField lengthEditBox;
    private hCheckBox outlineCheckBox;
    private boolean disableInput = false;
    private vector3df normal = vector3df.DIR_UP;

    public CylinderEmitterEditorPanel() {
        setTitle("Cylinder Emitter");
        setLayout(new RowLayout().setStartYGap(20).setStartXGap(10).setEndYGap(10));

        add(new hLabel("Center"), RowLayout.NewRow);
        centerEditor = new Vector3dEditor(this);
        centerEditor.setValueChangedEvent(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                changeCenter();
            }
        });

        radiusEditBox = new DefaultFloatTextField(0, 99999999);
        radiusEditBox.setPreferredSize(new Dimension(80, 20));
        radiusEditBox.setValueChangedEventNumber(new ValueChangedEvent<Float>() {
            @Override
            public void valueChanged(Float value) {
                if (!disableInput) {
                    changeRadius();
                }
            }
        });

        add(new hLabel("Radius:"));
        add(radiusEditBox, RowLayout.NewRow);

        lengthEditBox = new DefaultFloatTextField(0, 99999999);
        lengthEditBox.setPreferredSize(new Dimension(80, 20));
        lengthEditBox.setValueChangedEventNumber(new ValueChangedEvent<Float>() {
            @Override
            public void valueChanged(Float value) {
                if (!disableInput) {
                    changeLength();
                }
            }
        });

        add(new hLabel("Length:"));
        add(lengthEditBox, RowLayout.NewRow);

        outlineCheckBox = new hCheckBox("Only On Outline");

        outlineCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!disableInput) {
                    changeOutline();
                }
            }
        });

        add(outlineCheckBox, RowLayout.NewRow);
    }

    private void changeCenter() {
        vector3df center = centerEditor.getValue();
        emitter.setCenter(center);
    }

    private void changeRadius() {
        float radius = (float) radiusEditBox.getValue();
        emitter.setRadius(radius);
    }

    private void changeLength() {
        float length = (float) lengthEditBox.getValue();
        emitter.setLength(length);
    }

    private void changeOutline() {
        boolean outline = outlineCheckBox.isSelected();
        emitter.setOutline(outline);
    }

    @Override
    public void putFromEmmiter(IParticleEmitter particleEmitter) {
        disableInput = true;
        emitter = (IParticleCylinderEmitter) particleEmitter;
        radiusEditBox.setValue(emitter.getRadius());
        lengthEditBox.setValue(emitter.getLength());
        outlineCheckBox.setSelected(emitter.getOutline());
        centerEditor.setValue(emitter.getCenter());
        disableInput = false;
    }

    @Override
    public void putToEmmiter(IParticleEmitter emmiter) {
    }

    @Override
    public void renderEmitter(IVideoDriver driver) {
        driver.setMaterial(getMaterial());
        final float coeficient = 0.714285714f;
        vector3df center = emitter.getCenter();
        float length = emitter.getLength();
        float radius = emitter.getRadius() / coeficient;
        boolean outline = emitter.getOutline();
        vector3df lengthVector = new vector3df(0, length, 0);
        vector3df upPointPosition = center.addOperator(lengthVector);

        CircleDrawer drawerLow = new CircleDrawer(20, center, normal, radius);
        drawerLow.drawCircle();
        CircleDrawer drawerLow2 = null;
        if (outline) {
            drawerLow2 = new CircleDrawer(20, center, normal, radius - 2);
            drawerLow2.drawCircle();
        }

        CircleDrawer drawerHight = new CircleDrawer(20, upPointPosition, normal, radius);
        drawerHight.drawCircle();
        CircleDrawer drawerHight2;
        if (outline) {
            drawerHight2 = new CircleDrawer(20, upPointPosition, normal, radius - 2);
            drawerHight2.drawCircle();
        }

        int edgeCount = 10;
        float dAngle = 360 / (float) edgeCount;
        float currentAngle = 0;
        for (int i = 0; i < edgeCount; i++) {
            vector3df pos = drawerLow.getPoint(currentAngle);
            vector3df upPos = pos.addOperator(lengthVector);
            driver.draw3DLine(upPos, pos);
            if (outline) {
                pos = drawerLow2.getPoint(currentAngle);
                upPos = pos.addOperator(lengthVector);
                driver.draw3DLine(upPos, pos);
            }
            currentAngle += dAngle;
        }
    }

    public static void writeData(FileSection parentSection, IParticleEmitter emitter) throws IOException {
        IParticleCylinderEmitter spEmitter = (IParticleCylinderEmitter) emitter;
        FileSection sect = parentSection.createNewSection("cylinderEm");
        sect.writeVector("center", spEmitter.getCenter());
        sect.writeFloat("radius", spEmitter.getRadius());
        sect.writeFloat("length", spEmitter.getLength());
        sect.writeBoolean("outline", spEmitter.getOutline());
        sect.close();
    }

    public static IParticleCylinderEmitter loadData(IParticleSystemSceneNode partSystem, FileSection parentSection) throws IOException {
        IParticleCylinderEmitter emitter = partSystem.createCylinderEmitter(vector3df.NULLVECTOR, 1f, vector3df.DIR_UP, 1f);
        FileSection settings=parentSection.readSection(parentSection.getChunk("cylinderEm"));
        vector3df center = settings.readVector(settings.getChunk("center"));
        float radius = settings.readFloat(settings.getChunk("radius"));
        float length = settings.readFloat(settings.getChunk("length"));
        boolean outline = settings.readBoolean(settings.getChunk("outline"));

        emitter.setCenter(center);
        emitter.setRadius(radius);
        emitter.setLength(length);
        emitter.setOutline(outline);

        partSystem.setEmitter(emitter);
        settings.close();
        return emitter;
    }
}
